package com.androidplex.bucketlist;

import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.widget.Toast;

import com.androidplex.bucketlist.model.BucketListItem;
import com.androidplex.bucketlist.model.BucketListing;

import java.nio.charset.Charset;
import java.util.Locale;


/**
 * An activity representing a list of Items. This activity
 * has different presentations for handset and tablet-size devices. On
 * handsets, the activity presents a list of items, which when touched,
 * lead to a {@link ItemDetailActivity} representing
 * item details. On tablets, the activity presents the list of items and
 * item details side-by-side using two vertical panes.
 * <p>
 * The activity makes heavy use of fragments. The list of items is a
 * {@link ItemListFragment} and the item details
 * (if present) is a {@link ItemDetailFragment}.
 * <p>
 * This activity also implements the required
 * {@link ItemListFragment.Callbacks} interface
 * to listen for item selections.
 */
public class ItemListActivity extends FragmentActivity
        implements ItemListFragment.Callbacks {

    /**
     * Whether or not the activity is in two-pane mode, i.e. running on a tablet
     * device.
     */
    private boolean mTwoPane;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_item_list);

        if (findViewById(R.id.item_detail_container) != null) {
            // The detail container view will be present only in the
            // large-screen layouts (res/values-large and
            // res/values-sw600dp). If this view is present, then the
            // activity should be in two-pane mode.
            mTwoPane = true;

            // In two-pane mode, list items should be given the
            // 'activated' state when touched.
            ((ItemListFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.item_list))
                    .setActivateOnItemClick(true);
        }


        //NFC SEND
        NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (nfcAdapter == null) return;  // NFC not available on this device
        nfcAdapter.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback() {
            @Override
            public NdefMessage createNdefMessage(NfcEvent event) {


                int size = BucketListing.getSize() + 1;
                NdefRecord[] records = new NdefRecord[size];
                Log.i("ANDROID_NFC","Sending " + Integer.toString(size));
                records[0] = createNewTextRecord("Username", Locale.ENGLISH, true);
                for (int i = 1; i <= size; i++) {
                    Log.i("ANDROID_NFC","Sending 2" + BucketListing.ITEMS.get(i-1).getNFCString());
                    records[i] = createNewTextRecord(BucketListing.ITEMS.get(i-1).getNFCString(), Locale.ENGLISH, true);
                    Log.i("ANDROID_NFC","TEST " + records[i].getPayload());
                }

                NdefMessage message = new NdefMessage(records);

                return message;

            }
        }, this);


        //RECEIVE NFC

    }

    @Override
    public void onNewIntent(Intent intent){
        // part of RCV
        setIntent(intent);
        Log.d("ANDROID_TAG", intent.toString());
        //processIntent(intent);
    }

    @Override
    public void onResume(){
        // part of RECV
        super.onResume();

        if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())){
            processIntent(getIntent());
        }
    }

    @Override
    protected void onStart() {
        Log.d("ANDROID_TAG", getIntent().toString());
        super.onStart();
    }

    private void processIntent(Intent intent){
        //part of RECV
        Parcelable[] rawMsgs =  intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);

        // we should pray that only one message was sent
        NdefMessage msg = (NdefMessage) rawMsgs[0];
        Log.i("ANDROID_NFC","Hello! DEBUGGING in PROGRESS - 1");
        int newSize = msg.getRecords().length;
        Log.i("ANDROID_NFC","Hello! DEBUGGING in PROGRESS - 2 - " + Integer.toString(newSize));
        String payload = new String(msg.getRecords()[0].getPayload());
        Log.i("ANDROID_NFC","Hello! DEBUGGING in PROGRESS - 3 - " + payload);
        Toast.makeText(getApplicationContext(), "RECEIVED: " + payload, Toast.LENGTH_LONG).show();
        for (int i = 0; i < newSize; i++) {
            String record = msg.getRecords()[i+1].getPayload().toString();
            Log.i("ANDROID_NFC","Hello! DEBUGGING in PROGRESS - 4 - " + record);
            BucketListing.addEncodedItem(record);
        }
    }

    public static NdefRecord createNewTextRecord(String text, Locale locale, boolean encodeInUtf8) {

        // part of the NFC SEND
        byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));

        Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
        byte[] textBytes = text.getBytes(utfEncoding);

        int utfBit = encodeInUtf8 ? 0 : (1 << 7);
        char status = (char)(utfBit + langBytes.length);

        byte[] data = new byte[1 + langBytes.length + textBytes.length];
        data[0] = (byte)status;
        System.arraycopy(langBytes, 0, data, 1, langBytes.length);
        System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);

        return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
    }


    /**
     * Callback method from {@link ItemListFragment.Callbacks}
     * indicating that the item with the given ID was selected.
     */
    @Override
    public void onItemSelected(String id) {
        if (mTwoPane) {
            // In two-pane mode, show the detail view in this activity by
            // adding or replacing the detail fragment using a
            // fragment transaction.
            Bundle arguments = new Bundle();
            arguments.putString(ItemDetailFragment.ARG_ITEM_ID, id);
            ItemDetailFragment fragment = new ItemDetailFragment();
            fragment.setArguments(arguments);
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.item_detail_container, fragment)
                    .commit();

        } else {
            // In single-pane mode, simply start the detail activity
            // for the selected item ID.
            Intent detailIntent = new Intent(this, ItemDetailActivity.class);
            detailIntent.putExtra(ItemDetailFragment.ARG_ITEM_ID, id);
            startActivity(detailIntent);
        }
    }
}
